var status = 'collapsed';


var interstellar = {};
App.interstellarWrapper = function() {
    interstellar.is_commander_tab = false;
    interstellar.refreshedCacheKey = [];
    interstellar.tab_id = new Date().getTime() + '_' + _.random(1,100);
    interstellar.generateKey = function(name) {
        var suffix = App.user.id ? App.user.id : 'visitor';
        return name + '_' + suffix;
    };
    interstellar.getOpenedTabs = function(){
        return JSON.parse(window.localStorage.getItem(interstellar.generateKey('opened_tabs')));
    };
    interstellar.setOpenedTabs = function(opened_tabs){
        window.localStorage.setItem(interstellar.generateKey('opened_tabs'), JSON.stringify(opened_tabs));
    };
    interstellar.broadcastSocketEvent = function(name, payload){
        //To all other tabs, excluding self
        var event = {
            name: name,
            payload: payload
        };
        window.localStorage.setItem(interstellar.generateKey('socket_event'), JSON.stringify(event));
        //To self
        brain.broadcastEvent(name, payload);
    };
    interstellar.socketEventHandler = function(event){
        brain.broadcastEvent(event.name, event.payload);
    };

    interstellar.initCommanderTab = function(){
        if (!interstellar.is_commander_tab) {
            interstellar.is_commander_tab = true;
            //Handle Socket connections
            if (App.active) {
                var appUser = App.user;
                var username = appUser.username ? appUser.username : '';
                var id = appUser.id ? appUser.id : '';
                var avatar = appUser.avatar ? appUser.avatar : '';

                var socket = App.socketUrl
                    +'?username=' + encodeURIComponent(username)
                    +'&userid=' + encodeURIComponent(id)
                    +'&avatar=' + encodeURIComponent(avatar);

                var socketConnection = function (socket) {

                    App.socket = io(socket, {upgrade: false, transports: ['websocket'], reconnection: false, rejectUnauthorized: false, secure: true});

                    var room = 'website_' + App.website.id;
                    App.socket.emit('user join', room);

                    //mapping
                    App.socket.on('user join', function(payload){
                        interstellar.broadcastSocketEvent('CS-USER-JOIN-INBOUND', payload);
                    });

                    App.socket.on('user leave', function(payload){
                        interstellar.broadcastSocketEvent('CS-USER-LEAVE-INBOUND', payload);
                    });

                    App.socket.on('message', function(payload){
                        interstellar.broadcastSocketEvent('CS-MESSAGE-INCOMING', payload);
                        var messages = interstellar.getCachedResource('messages_' + payload.room_id);
                        messages = messages.length ? messages : [];
                        if(!_.find(messages, function(msg){return msg.id == payload.id})){
                            messages.push(payload);
                            interstellar.setCachedResource('messages_' + payload.room_id, messages);
                        }


                        if (payload.room_type != 'private') {
                            var world_channel_messages = interstellar.getCachedResource('messages_' + App.website.worldChannelRoomId);
                            world_channel_messages = world_channel_messages.length ? world_channel_messages : [];
                            if(!_.find(world_channel_messages, function(msg){return msg.id == payload.id})){
                                world_channel_messages.push(payload);
                                interstellar.setCachedResource('messages_' + App.website.worldChannelRoomId, world_channel_messages);
                            }

                        }

                        var cached_rooms = interstellar.getCachedResource('rooms_of_' + App.user.id);
                        if (cached_rooms) {
                            _.each(cached_rooms, function(room, key){
                                if (room.id == payload.room_id || room.is_world_channel) {
                                    cached_rooms[key].msgs[0] = payload;
                                }
                            });

                        }
                        interstellar.setCachedResource('rooms_of_' + App.user.id, cached_rooms);


                    });

                    App.socket.on('message update', function(payload){
                        interstellar.broadcastSocketEvent('CS-MESSAGE-UPDATE', payload);
                        interstellar.clearCachedResource('messages_' + payload.room_id);
                        interstellar.clearCachedResource('messages_' + App.website.worldChannelRoomId);
                        interstellar.clearCachedResource('rooms_of_' + App.user.id);
                    });

                    App.socket.on('message remove', function(payload){
                        interstellar.broadcastSocketEvent('CS-MESSAGE-REMOVE', payload);
                        interstellar.clearCachedResource('messages_' + payload.room_id);
                        interstellar.clearCachedResource('messages_' + App.website.worldChannelRoomId);
                        interstellar.clearCachedResource('rooms_of_' + App.user.id);
                    });

                    App.socket.on('user block', function(payload){
                        interstellar.broadcastSocketEvent('CS-USER-BLOCK', payload);
                    });

                    App.socket.on('user unblock', function(payload){
                        interstellar.broadcastSocketEvent('CS-USER-UNBLOCK', payload);
                    });

                    App.socket.on('user count', function (count) {
                        interstellar.broadcastSocketEvent('CS-USER-COUNT', count);
                    });

                    App.socket.on('notification', function(payload){
                        // Notification type: 100 = reply, 200 = like
                        interstellar.broadcastSocketEvent('CS-NOTIFICATION', payload);
                        interstellar.clearCachedResource('notification');
                    });

                    App.socket.on('private room blocked', function (roomId) {
                        interstellar.broadcastSocketEvent('CS-UPDATE-ROOM-TO-BLOCKED', roomId);
                    });

                    App.socket.on('private room unblocked', function (roomId) {
                        interstellar.broadcastSocketEvent('CS-UPDATE-ROOM-TO-UNBLOCKED', roomId);
                    });

                    App.socket.on('announcement show', function (announcement) {
                        interstellar.broadcastSocketEvent('CS-ANNOUNCEMENT-SHOW', announcement);
                        interstellar.clearCachedResource('announcement');
                    });

                    App.socket.on('announcement remove', function (announcement) {
                        interstellar.broadcastSocketEvent('CS-ANNOUNCEMENT-REMOVE', announcement);
                        interstellar.clearCachedResource('announcement');
                    });


                    //TODO Deprecate all client to server bound socket events
                    //TODO convert to server to server event bus if necessary
                    // brain.subscribeToEvent('CS-USER-LEAVE-OUTBOUND', function(room){
                    //     App.socket.emit('user leave', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-USER-JOIN-OUTBOUND', function(room){
                    //     App.socket.emit('user join', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-JOIN-IO-ACTIVITY', function(room){
                    //     App.socket.emit('join io activity', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-JOIN-IO-ACTIVITY', function(room){
                    //     App.socket.emit('join io activity', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-LEAVE-IO-ACTIVITY', function(room){
                    //     App.socket.emit('leave io activity', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-BLOCK-PRIVATE-CHAT', function (room) {
                    //     App.socket.emit('private room blocked', room);
                    // });
                    //
                    // brain.subscribeToEvent('CS-UNBLOCK-PRIVATE-CHAT', function (room) {
                    //     App.socket.emit('private room unblocked', room);
                    // });
                };

                socketConnection(socket);

                brain.subscribeToEvent('UPDATE_SOCKET', function () {
                    // Refresh socket connection after user login
                    var appUser = App.user;
                    var username = appUser.username ? appUser.username : '';
                    var id = appUser.id ? appUser.id : '';
                    var avatar = appUser.avatar ? appUser.avatar : '';

                    var newSocket = App.socketUrl
                        +'?username=' + encodeURIComponent(username)
                        +'&userid=' + encodeURIComponent(id)
                        +'&avatar=' + encodeURIComponent(avatar);

                    App.socket.close();
                    socketConnection(newSocket);
                    socket = newSocket;
                });


                setTimeout(function(){
                    var connection_retry_count = 0;
                    setInterval(function(){
                        if (!App.socket.connected) {
                            if (connection_retry_count < 5) {
                                $('._spinner-container').addClass('show');
                                connection_retry_count++;
                                socketConnection(socket);
                            } else {
                                interstellar.broadcastSocketEvent('NOTE', {
                                    type: 'warning',
                                    message: '与推送服务的连接出现了问题，请手动刷新哦。',
                                    stay: true
                                });
                            }
                        } else {
                            if (connection_retry_count > 0) {
                                connection_retry_count = 0;

                                //TODO make it broadcast event
                                setTimeout(function () {
                                    $('._spinner-container').removeClass('show');
                                }, 500);
                            }
                        }
                    }, 5000);
                }, 5000);
                // App.initRooms();
            }
        }
    };
    interstellar.isCacheExpired = true;


    //initialize
    var opened_tabs = interstellar.getOpenedTabs();
    if (!opened_tabs || opened_tabs.length==0) {
        opened_tabs = [interstellar.tab_id];
        interstellar.initCommanderTab();

        var lastTabClosedTime = window.localStorage.getItem(interstellar.generateKey('last_tab_closed_time'));
        if (lastTabClosedTime) {
            lastTabClosedTime = parseInt(lastTabClosedTime, 10);
            var currentTime = new Date().getTime();
            if (currentTime - lastTabClosedTime <= 10000) {
                interstellar.isCacheExpired = false;
            }
        }

    } else {
        opened_tabs.push(interstellar.tab_id);
        interstellar.isCacheExpired = false;
    }

    interstellar.setOpenedTabs(opened_tabs);
    //initialize

    //health check
    interstellar.healthyTabs = [interstellar.tab_id];
    setInterval(function(){
        //heartbeat for health checking
        window.localStorage.setItem(interstellar.generateKey('heartbeat'), interstellar.tab_id);
    }, 10000);

    var claimedHealthyTabs = interstellar.getOpenedTabs();
    setTimeout(function(){
        var actualHealthyTabs = interstellar.healthyTabs;
        var deadTabs = _.difference(claimedHealthyTabs, actualHealthyTabs);
        deadTabs = _.intersection(deadTabs, claimedHealthyTabs);

        if (deadTabs.length) {
            _czc.push(["_trackEvent", 'clean_up', 'dead_tabs']);
        }

        var currentTabs = interstellar.getOpenedTabs();
        _.each(deadTabs, function(deadTab){
            var index = currentTabs.indexOf(deadTab);
            if (index > -1) {
                currentTabs.splice(index, 1);
            }
        });
        interstellar.setOpenedTabs(currentTabs);
    }, 30000);
    //health check


    //cache handling
    interstellar.enableFrontendCaching = false;
    interstellar.getCachedResource = function(uri) {

        if (!interstellar.enableFrontendCaching) {
            return false;
        }

        var key = 'cache_' + App.website.id + '_' + uri;
        var refreshed = false;
        if (interstellar.refreshedCacheKey.indexOf(key) > -1) {
            refreshed = true;
        }
        if (!interstellar.isCacheExpired || refreshed) {
            var value = window.localStorage.getItem(interstellar.generateKey(key));
            if (value) {
                return JSON.parse(value);
            } else {
                return false;
            }
        } else {
            return false;
        }
    };

    interstellar.setCachedResource = function(uri, value) {

        if (!interstellar.enableFrontendCaching) {
            return false;
        }

        var key = 'cache_' + App.website.id + '_' + uri;
        interstellar.refreshedCacheKey.push(key);
        window.localStorage.setItem(interstellar.generateKey(key), JSON.stringify(value));
    };

    interstellar.clearCachedResource = function(uri) {

        if (!interstellar.enableFrontendCaching) {
            return false;
        }

        var key = 'cache_' + App.website.id + '_' + uri;
        window.localStorage.setItem(interstellar.generateKey(key), '');
    };
    //cache handling


    //tear down
    window.onbeforeunload = function(e) {
        var opened_tabs = interstellar.getOpenedTabs();
        var index = opened_tabs.indexOf(interstellar.tab_id);
        if (index > -1) {
            opened_tabs.splice(index, 1);
            interstellar.setOpenedTabs(opened_tabs);
            if (opened_tabs.length == 0) {
                window.localStorage.setItem(interstellar.generateKey('last_tab_closed_time'), new Date().getTime());
            }
        }
    };
    //tear down

    //event handling
    $(window).on('storage', function(e){
        var event = e.originalEvent;
        switch (event.key) {
            case interstellar.generateKey('opened_tabs'):
                var opened_tabs = interstellar.getOpenedTabs();
                if (opened_tabs.length) {
                    if (opened_tabs[0] == interstellar.tab_id) {
                        interstellar.initCommanderTab();
                    }
                }
                break;
            case interstellar.generateKey('socket_event'):
                interstellar.socketEventHandler(JSON.parse(event.newValue));
                break;
            case interstellar.generateKey('heartbeat'):
                var tab_id = event.newValue;
                if (interstellar.healthyTabs.indexOf(tab_id) < 0) {
                    interstellar.healthyTabs.push(tab_id);
                }
                break;
        }
    });
    //event handling
};


window.postMessageWrapper = function(status, domain) {
    if (App.website.mobile == '1') {
        //nothing
    } else if (window.development) {
        //nothing, uncomment following code to test in lab/sample
        window.parent.postMessage(status, domain);
    } else {
        try {
            window.parent.postMessage(status, domain);
        } catch (e) {
            //nothing
        }

    }
};


window.addEventListener('message', function(event) {
    if (typeof event.data === 'string') {
        if(event.data === 'IN_XIANLIAO'){

            brain.broadcastEvent('UPDATE_CURSOR_UNIVERSE', 'xianliao');

        }else if (event.data === 'IN_COMMUNITY'){

            brain.broadcastEvent('UPDATE_CURSOR_UNIVERSE', 'community');

        }else if(event.data === 'UPDATE_FOOTPRINT'){

            brain.broadcastEvent('UPDATE_FOOTPRINT', true);

        }
    }else if(typeof event.data === 'object'){
        if(event.data.name == 'SET_DOMAIN_NAME'){
            brain.setData('postmessageDomain', event.data.payload);
        }
    }
}, false);



App.getNow = function () {
    var d = new Date();
    return parseInt(d.getTime());

};

App.relativeTime = function (ts) {

    if (!ts) {
        return '';
    }

    var now = App.getNow();
    var elapse = parseInt((now - ts) / 1000, 10);

    var relativeTime = '--';
    if (elapse < 60) {
        relativeTime = '刚刚';
    } else if (elapse < 3600) {
        relativeTime = parseInt(elapse/60, 10) + '分钟前';
    } else if (elapse <= 86400) {
        relativeTime =  parseInt(elapse/3600, 10) + '小时前';
    } else if (elapse <= 604800) {
        relativeTime =  parseInt(elapse/86400, 10) + '天前';
    } else if (elapse <= 2592000) {
        relativeTime =  parseInt(elapse/604800, 10) + '周前';
    } else {
        relativeTime =  parseInt(elapse/2592000, 10) + '月前';
    }

    return relativeTime;
};

App.levelCache = {};
App.level = function (points) {
    if (!points) {
        points = 0;
    }

    var key = "points_" + points;
    var value = App.levelCache[key];

    if (!value) {
        var level = 0;
        var incremental = 10;
        var currentLevelPoints = 10;
        var nextLevelTotalPoints = 10;

        while (points - nextLevelTotalPoints >= 0) {
            level++;
            currentLevelPoints = currentLevelPoints + incremental;
            nextLevelTotalPoints += currentLevelPoints;
        }

        var pointsToGo = nextLevelTotalPoints-points;
        var pointsSoFar = currentLevelPoints-pointsToGo;

        value = {
            level: level,
            pointsToGo: pointsToGo,
            pointsSoFar: pointsSoFar,
            currentLevelPoints: currentLevelPoints,
            progressRatio: 100 * pointsSoFar / currentLevelPoints
        };

        App.levelCache[key] = value;

    }

    return value;
};

App.canRegister = function () {
    return   App.website.type == 300;
};

App.isRegisteredToWebsite = function () {
    switch (App.website.type) {
        case 100:
        case 200:
            return (typeof brain.getData('App.user').id != 'undefined' && brain.getData('App.user').id);
            break;
        case 300:
            return (typeof brain.getData('App.user').id != 'undefined' && brain.getData('App.user').id);
            break;
    }

};

App.canSubmit = function () {
    switch (App.website.type) {
        case 100:
        case 200:
            return App.isRegisteredToWebsite();
            break;
        case 300:
            return true;
            break;
    }
};



App.adsSawForTheDay = function(){
    var adsSaw = localStorage.getItem("adsSaw") ? localStorage.getItem("adsSaw") : 0;
    adsSaw = parseInt(adsSaw, 10);
    return adsSaw;
};

App.showPopupAds = function (adType) {

    //TODO determine by App.website.disable_ads
    //var enabledWebsiteList = [10117, 10179, 10201, 10098, 10182, 11774, 12398];
    if (!window.development && (App.website.disable_ads == 1 || App.website.disable_ads == '1')) {
        return false;
    }


    var showPopupAds = false;

    var lastSawAdsTimestamp = localStorage.getItem("lastSawAdsTimestamp") ? localStorage.getItem("lastSawAdsTimestamp") : 0;
    lastSawAdsTimestamp = parseInt(lastSawAdsTimestamp, 10);
    if (Date.now() - lastSawAdsTimestamp > 86400000) {
        localStorage.setItem("lastSawAdsTimestamp", 0);
        localStorage.setItem("adsSaw", 0);
    }

    var adsSaw = localStorage.getItem("adsSaw") ? localStorage.getItem("adsSaw") : 0;
    adsSaw = parseInt(adsSaw, 10);

    if (App.user.is_admin != 1) {

        if (App.level(App.user.points).level < 50) {

            if (adType == 'BIG') {
                showPopupAds = true;
            }

            if (adsSaw < 100) {

                showPopupAds = true;
            }
        }
    }

    return showPopupAds;
};

App.sawPopupAds = function () {
    var adsSaw = localStorage.getItem("adsSaw") ? localStorage.getItem("adsSaw") : 0;
    adsSaw = parseInt(adsSaw, 20);
    adsSaw+=1;

    localStorage.setItem("adsSaw", adsSaw);
    localStorage.setItem("lastSawAdsTimestamp", Date.now());

};

App.closeAdsForTheDay = function () {
    var adsSaw = localStorage.getItem("adsSaw") ? localStorage.getItem("adsSaw") : 0;
    adsSaw = parseInt(adsSaw, 10);
    if (adsSaw >= 10 || true) {
        localStorage.setItem("adsSaw", 999);
        localStorage.setItem("lastSawAdsTimestamp", Date.now());
    }
};


App.adsDuration = function () {
    var adsSaw = localStorage.getItem("adsSaw") ? localStorage.getItem("adsSaw") : 0;
    adsSaw = parseInt(adsSaw, 10);

    if (adsSaw < 30) {
        return 10000;
    } else {
        return 9999999;
    }

};

App.addRecentEmoji = function (url) {
    var emojiData = localStorage.getItem('emojiData_' + App.user.id);
    var emojiList = emojiData ? JSON.parse(emojiData) : [];

    emojiList = _.filter(emojiList, function(item){
        return item != url;
    });
    emojiList.unshift(url);
    emojiList = emojiList.slice(0, 12);


    var emojiDataUpdated = JSON.stringify(emojiList);
    localStorage.setItem('emojiData_' + App.user.id, emojiDataUpdated);
    return emojiList;

};

App.getRecentEmoji = function () {
    var emojiData = localStorage.getItem('emojiData_' + App.user.id);
    var emojiList = emojiData ? JSON.parse(emojiData) : [];
    return emojiList;
};

App.userAvatar = function (url) {
    return  url || 'https://cdn.xianliao.me/images/avatar_o.png';
};

App.isSSL = function(){
    return location.protocol === 'https:';
};

App.appInitWrapper = function() {

    if (!App.active) {
        $("body").hide();
    }

    //Inform embed js xianliao iframe is loaded
    window.postMessageWrapper('IFRAME_LOADED', App.website.domain);

    //Run interstellar codes
    App.interstellarWrapper();


    //Tracking
    if (!window.development) {
        if (window.location.protocol == 'http:') {
            $(document.body).append('<div style="display: none;"><script src="https://s4.cnzz.com/z_stat.php?id=1261210977&web_id=1261210977" language="JavaScript"></script></div>');
        } else {
            $(document.body).append('<div style="display: none;"><script src="https://s13.cnzz.com/z_stat.php?id=1261210977&web_id=1261210977" language="JavaScript"></script></div>');
        }

        $(document.body).append('<script src="https://cdn.xianliao.me/assets/ga.js" language="JavaScript"></script>');
    }

    //Store data in brain
    brain.setData('App.user', App.user);
    brain.setData('App.website', App.website);


    // Only active input fields in use
    if (window.isIOS) {
        $(document).on( "focus", "input, textarea", function() {
            console.log('read only trigger');
            $('input, textarea').not(this).attr("readonly", "readonly");
        });

        $(document).on( "blur", "input, textarea", function() {
            console.log('read only remove');
            $('input, textarea').removeAttr("readonly");
        });
    }

    // --- START OF BLACK MAGIC
    $(document).on('mousemove', function (e) {
        var payload = {
            name: 'WORMHOLE',
            cursor: {
                xPos: e.pageX,
                yPos: e.pageY
            }
        };
        window.postMessageWrapper(payload, App.website.domain);
    });


    $(window).resize(function(){
        updateFootPrint();
    });

    brain.subscribeToEvent('UPDATE_FOOTPRINT', function () {
        updateFootPrint();
    });

    brain.subscribeToEvent('FULL_PAGE_FOOTPRINT', function () {
        window.postMessageWrapper('FULL_PAGE_FOOTPRINT', App.website.domain);
    });

    var updateFootPrint = function(){

        var boundaries = getBoundaries();

        var payload = {
            name: 'UPDATE_FOOTPRINT',
            data: boundaries
        };

        window.postMessageWrapper(payload, App.website.domain);
    };

    var getBoundaries = function(){
        var containers = document.getElementsByClassName('xianliao_component');
        var boundaries = [];
        if (containers.length > 0){
            for (i = 0; i < containers.length; i++ ){
                var rect = containers[i].getBoundingClientRect();
                boundaries.push({top: rect.top, left: rect.left, right: rect.right, bottom: rect.bottom, height:rect.height, width:rect.width});
            }
        }
        return boundaries;
    };

    // --- END OF BLACK MAGIC
};
